//模板方法模式由两部分结构组成：抽象父类和具体的实现子类。通常在抽象父类中封装了子类的算法框架，也包括
//实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类，也继承了整个算法结构，并且
//可以选择重写父类的方法

import fs from 'fs';

abstract class DataParser{
    data: string = '';
    out: any = null;

    //这就是所谓的模板方法
    parse(pathUrl: string){
        this.readFile(pathUrl)
        this.doParsing();
        this.printData();
    }

    readFile(pathUrl: string){
        this.data = fs.readFileSync(pathUrl,'utf8');
    }

    abstract doParsing(): void;

    printData(){
        console.log(this.out)
    }
}

class CSVParser extends DataParser{
    doParsing(){
        this.out = this.data.split(',');
    }
}

class MarkupParser extends DataParser{
    doParsing(){
        this.out = this.data.match(/<\w+>.*<\/\w+>/gim);
    }
}

const csvPath = './data.csv';
const mdPth = './design-pattern.md';

new CSVParser().parse(csvPath);
new MarkupParser().parse(mdPth);


//应用场景
//1.算法的整体步骤固定，但其中个别部分易变时，这时候可以使用模板方法模式，将容易变得部分抽象出来，供子类实现
//2.当需要控制子类得扩展时，模板方法只在特定点调用钩子操作，这样就只允许在这些点进行扩展